//
//  SEGIAnalyticsManager.m
//  test
//
//  Created by 刘山 on 2017/11/28.
//  Copyright © 2017年 刘山. All rights reserved.
//

#define kUploadLogTime @"com.seg.userDefault.analytics.uploadTime"

#import "SEGIAnalyticsManager.h"
#import "SEGIAnalyticsLogEventModel.h"
#import "SEGIAnalyticsComm.h"
#import "SEGIAnalyticsLogErrorModel.h"

#import "SEGIAnalyticsPageDBManager.h"
#import "SEGIAnalyticsEventDBManager.h"
#import "SEGIAnalyticsLogErrorDBManager.h"
#import "SEGIAnalyticsNetWorkManager.h"

#if __has_include(<Commom/SEGModel.h>)
#import <Commom/SEGModel.h>
#else
#import "SEGModel.h"
#endif

@implementation SEGIAnalyticsConfig
-(instancetype)init{
    if (self == [super init]) {
        _userId = @"" ;//用户的唯一标识
        _userName = @"" ;//用户的名称
        _age = @"0" ;//用户年龄
        _sex = @"1" ;//用户性别（1、男 2、女）
        _degree = @"" ;//用户学历
        _occupation = @"" ;//用户职业
        _communityID = @"" ;//小区ID
        _communityName = @"" ;//小区名称
        //        _projectId = @"" ;//事件 id
        //        _projectName = @"" ;//事件 名称
        //        _plate = @"" ;//事件 版块
        //        _sortNumber = @"" ;//事件 顺序号
        //        _isPraise = @"0" ;//事件 是否留言点赞
        //        _isComment = @"0" ;//事件 是否留言评论
        //        _shareChannel = @"" ;//事件 分享渠道
    }
    return self;
}
@end


@interface SEGIAnalyticsManager()
@property (nonatomic, strong)SEGIAnalyticsConfig *analyticsConfig;
@property (nonatomic, assign)BOOL logEnabled;//是否打开日志
@property (nonatomic, strong)NSTimer *logTimer;
@end

@implementation SEGIAnalyticsManager

static id _SEGIAnalyticsManager;
+ (instancetype)sharedAnalyticsManager
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _SEGIAnalyticsManager = [[self alloc] init];
    });
    return _SEGIAnalyticsManager;
}

-(instancetype)init{
    if (self == [super init]) {
        _analyticsConfig = [[SEGIAnalyticsConfig alloc]init];
        _lastPage = @"";
        _logEnabled = NO;
        
        [SEGIAnalyticsPageDBManager segPageCreateTable];
        [SEGIAnalyticsEventDBManager segPageCreateTable];
        [SEGIAnalyticsLogErrorDBManager segLogErrorCreateTable];
        
        CGFloat uploadTime = [[NSUserDefaults standardUserDefaults] floatForKey:kUploadLogTime];
        if (!uploadTime || uploadTime <= 0) {
            [self segLogSendInterval:10.0];
        }else{
            [self setTimerUploadWithTimeInterval:uploadTime];
        }
        
        [self segEvetRegister];
    }
    return self;
}

-(void)segEvetRegister{
    // 系统从后台激活:确定session开始
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(segDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
    // 系统从即将进入后台：确定session结束
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(segWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
    // 消息来获取appcrash信息, 当app crash时，相当于结束该session
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(segWillTerminate:) name:UIApplicationWillTerminateNotification object:nil];
    // 消息来获取appcrash信息, 当app crash时，相当于结束该session
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(segDidFinishLaunching:) name:UIApplicationDidFinishLaunchingNotification object:nil];
}

-(void)segDidBecomeActive:(NSNotification*)sender{
    if (![SEGIAnalyticsManager sharedAnalyticsManager].openAnalytics) return;
    self.sscode = [SEGIAnalyticsComm segSessionCode];
    [SEGIAnalyticsNetWorkManager segUploadAnalyticsEventData];//上传统计数据
    if (self.logTimer) {
        [self.logTimer setFireDate:[NSDate distantPast]];
    }
}

-(void)segWillResignActive:(NSNotification*)sender{
    if (![SEGIAnalyticsManager sharedAnalyticsManager].openAnalytics) return;
    if (self.logTimer) {
        [self.logTimer setFireDate:[NSDate distantFuture]];
    }
}

-(void)segWillTerminate:(NSNotification*)sender{
    if (![SEGIAnalyticsManager sharedAnalyticsManager].openAnalytics) return;
}

-(void)segDidFinishLaunching:(NSNotification*)sender{
    if (![SEGIAnalyticsManager sharedAnalyticsManager].openAnalytics) return;
    [SEGIAnalyticsNetWorkManager segUploadAnalyticsErrorData];//上传错误数据
}

/**
 * 初始化统计模块
 * @author Sam
 * @param configure  外部参数
 */
- (void) segStartWithConfigure:(SEGIAnalyticsConfig *)configure{
    self.analyticsConfig = configure;
}

/**
 * 时设定log发送间隔
 * @author Sam
 * @param second  发送的log的时间间隔，最小为90秒
 */
- (void)segLogSendInterval:(CGFloat)second{
    second = second < 10.0 ? second:10.0;
    [[NSUserDefaults standardUserDefaults]setFloat:second forKey:kUploadLogTime];
    [self setTimerUploadWithTimeInterval:second];
}

-(void)setTimerUploadWithTimeInterval:(CGFloat)timeInterval{
    if (self.logTimer) {
        [self.logTimer invalidate];
        self.logTimer = nil;
    }
    self.logTimer = [NSTimer timerWithTimeInterval:timeInterval target:self selector:@selector(uploadLogs) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.logTimer forMode:NSDefaultRunLoopMode];
}

-(void)uploadLogs{
    if (![SEGIAnalyticsManager sharedAnalyticsManager].openAnalytics) return;
    [SEGIAnalyticsNetWorkManager segUploadAnalyticsEventData];//上传统计数据
}


/**
 * 事件统计
 * @author Sam
 * @param eventId  事件对应的ID
 */
-(void)segEvent:(NSString *)eventId{
    if (![SEGIAnalyticsManager sharedAnalyticsManager].openAnalytics) return;
    SEGIAnalyticsLogEventModel *data = [SEGIAnalyticsLogEventModel new];
    data.pf = kBundleIdentifier;
    data.evtType = @"2";//页面事件、操作事件
    data.evtName = eventId;
    data.id = [SEGIAnalyticsComm segSessionCode];
    data.dvcCode = [SEGIAnalyticsComm uuid];
    data.dvcType = [SEGIAnalyticsComm segDeviceModel];
    data.dvcBrd = SEGDeviceBrandApple;
    data.dvcVer = [SEGIAnalyticsComm segMachineModelName];
    data.dvcSys = [SEGIAnalyticsComm segDeviceSystemName];
    data.dvcSysVer = [SEGIAnalyticsComm segDeviceSystemVersion];
    data.pfVer = kAppVersion;
    data.network = [SEGIAnalyticsComm segDeviceNetworkStatus];
    data.usrId = self.analyticsConfig.userId;
    data.usrName = self.analyticsConfig.userName;
    data.age = self.analyticsConfig.age;
    data.sex = self.analyticsConfig.sex;
    data.degree = self.analyticsConfig.degree;
    data.occupation = self.analyticsConfig.occupation;
    data.ssCode = self.sscode;
    data.startTime = [SEGIAnalyticsComm segCurrentTimeStamp];
    data.kpTime = @"0";
    data.lastPage = self.lastPage;
    NSMutableDictionary *dataJson = [NSMutableDictionary dictionaryWithDictionary:[data yy_modelToJSONObject]];
    [SEGIAnalyticsEventDBManager segEventInsertWithData:dataJson];
}

/**
 * 事件统计
 * @author Sam
 * @param eventId  事件对应的ID
 * @param attributes  业务属性字典
 */
-(void)segEvent:(NSString *)eventId attributes:(NSDictionary *)attributes{
    if (![SEGIAnalyticsManager sharedAnalyticsManager].openAnalytics) return;
    
    SEGIAnalyticsLogEventModel *data = [SEGIAnalyticsLogEventModel new];
    data.pf = kBundleIdentifier;
    data.evtType = @"2";//页面事件、操作事件
    data.evtName = eventId;
    data.id = [SEGIAnalyticsComm segSessionCode];
    data.dvcCode = [SEGIAnalyticsComm uuid];
    data.dvcType = [SEGIAnalyticsComm segDeviceModel];
    data.dvcBrd = SEGDeviceBrandApple;
    data.dvcVer = [SEGIAnalyticsComm segMachineModelName];
    data.dvcSys = [SEGIAnalyticsComm segDeviceSystemName];
    data.dvcSysVer = [SEGIAnalyticsComm segDeviceSystemVersion];
    data.pfVer = kAppVersion;
    data.network = [SEGIAnalyticsComm segDeviceNetworkStatus];
    data.usrId = self.analyticsConfig.userId;
    data.usrName = self.analyticsConfig.userName;
    data.age = self.analyticsConfig.age;
    data.sex = self.analyticsConfig.sex;
    data.degree = self.analyticsConfig.degree;
    data.occupation = self.analyticsConfig.occupation;
    data.ssCode = self.sscode;
    data.startTime = [SEGIAnalyticsComm segCurrentTimeStamp];
    data.kpTime = @"0";
    data.lastPage = self.lastPage;
    
    NSMutableDictionary *dataJson = [NSMutableDictionary dictionaryWithDictionary:[data yy_modelToJSONObject]];
    
    [attributes enumerateKeysAndObjectsUsingBlock:^(NSString*  _Nonnull key, NSString*  _Nonnull obj, BOOL * _Nonnull stop) {
        [dataJson setObject:obj forKey:key];
    }];
    
    [SEGIAnalyticsEventDBManager segEventInsertWithData:dataJson];
}

/**
 * 统计进入的页面
 * 使用方法：必须配对调用segBeginLogPageView:和segEndLogPageView:两个函数来完成自动统计，
 * 若只调用某一个函数不会生成有效数据。
 * @author Sam
 * @param pageName  页面的名称
 */
- (void)segBeginLogPageView:(NSString *)pageName{
    if (![pageName hasPrefix:@"SEG"]) return;
    if (![SEGIAnalyticsManager sharedAnalyticsManager].openAnalytics) return;
    
    [SEGIAnalyticsPageDBManager
     segPageInsertWithPageName:pageName
     startTime:[SEGIAnalyticsComm segCurrentTimeStamp]];
    
    //if (self.logEnabled){
    NSLog(@"SEGIAnalyticsLOG: pageBegin=%@, beginTime:%@",pageName,[SEGIAnalyticsComm segCurrentTimeStamp]);
    //}
}

/**
 * 统计退出的页面
 * 使用方法：必须配对调用segBeginLogPageView:和segEndLogPageView:两个函数来完成自动统计，
 * 若只调用某一个函数不会生成有效数据。
 * @author Sam
 * @param pageName  页面的名称
 */
- (void)segEndLogPageView:(NSString *)pageName{
    if (![pageName hasPrefix:@"SEG"]) return;
    if (![SEGIAnalyticsManager sharedAnalyticsManager].openAnalytics) return;
    
    pageName = (pageName && [pageName isKindOfClass:[NSString class]] ) ? pageName : @"";
    
    if (pageName.length <= 0) return;
    
    SEGIAnalyticsPageModel *dataCash = [SEGIAnalyticsPageDBManager segPageQuryWithPageName:pageName];
    if (!dataCash)return;
    
    NSInteger eTime = [SEGIAnalyticsComm segCurrentTimeStamp].integerValue;
    NSInteger sTime = dataCash.startTimeStamp.integerValue;
    NSInteger kpCurrentTime = eTime - sTime;
    kpCurrentTime = kpCurrentTime > 0 ? kpCurrentTime : 1;
    
    SEGIAnalyticsLogEventModel *data = [SEGIAnalyticsLogEventModel new];
    data.pf = kBundleIdentifier;
    data.evtType = @"1";//页面操作事件
    data.evtName = pageName;
    data.id = [SEGIAnalyticsComm segSessionCode];
    data.dvcCode = [SEGIAnalyticsComm uuid];
    data.dvcType = [SEGIAnalyticsComm segDeviceModel];
    data.dvcBrd = SEGDeviceBrandApple;
    data.dvcVer = [SEGIAnalyticsComm segMachineModelName];
    data.dvcSys = [SEGIAnalyticsComm segDeviceSystemName];
    data.dvcSysVer = [SEGIAnalyticsComm segDeviceSystemVersion];
    data.pfVer = kAppVersion;
    data.network = [SEGIAnalyticsComm segDeviceNetworkStatus];
    data.usrId = self.analyticsConfig.userId;
    data.usrName = self.analyticsConfig.userName;
    data.age = self.analyticsConfig.age;
    data.sex = self.analyticsConfig.sex;
    data.degree = self.analyticsConfig.degree;
    data.occupation = self.analyticsConfig.occupation;
    data.ssCode = self.sscode;
    data.lastPage = self.lastPage;
    data.startTime = dataCash.startTimeStamp;
    data.kpTime = [NSString stringWithFormat:@"%ld",(long)kpCurrentTime];
    self.lastPage = pageName;
    
    NSMutableDictionary *dataJson = [NSMutableDictionary dictionaryWithDictionary:[data yy_modelToJSONObject]];
    [SEGIAnalyticsEventDBManager segEventInsertWithData:dataJson];
    
    //    if (self.logEnabled) {
    NSLog(@"SEGIAnalyticsLOG: pageEnd=%@, duration:%@",pageName,[NSString stringWithFormat:@"%ld",(long)kpCurrentTime]);
    //    }
}

/**
 * 统计报错
 * @author Sam
 * @param stacktrace  错误堆栈信息
 * @param digest  错误摘要(错误的第一行)
 */
-(void)segLogError:(NSString *)stacktrace digest:(NSString*)digest{
    if (![SEGIAnalyticsManager sharedAnalyticsManager].openAnalytics) return;
    
    SEGIAnalyticsLogErrorModel *data = [SEGIAnalyticsLogErrorModel new];
    data.pf = kBundleIdentifier;
    data.id = [SEGIAnalyticsComm segSessionCode];
    data.dvcCode = [SEGIAnalyticsComm uuid];
    data.dvcType = [SEGIAnalyticsComm segDeviceModel];
    data.dvcBrd = SEGDeviceBrandApple;
    data.dvcVer = [SEGIAnalyticsComm segMachineModelName];
    data.dvcSys = [SEGIAnalyticsComm segDeviceSystemName];
    data.dvcSysVer = [SEGIAnalyticsComm segDeviceSystemVersion];
    data.pfVer = kAppVersion;
    data.network = [SEGIAnalyticsComm segDeviceNetworkStatus];
    data.createTime = [SEGIAnalyticsComm segCurrentTimeStamp];
    data.digest = digest;
    data.stacktrace = stacktrace;
    
    [SEGIAnalyticsLogErrorDBManager segLogErrorInsertWithData:data];
}

/**
 * 是否打开日志
 * @author Sam
 */
- (void)setSegLogEnabled:(BOOL)value{
}

-(NSString *)sscode{
    if (!_sscode || _sscode.length <= 0) {
        _sscode = [SEGIAnalyticsComm segSessionCode];
    }
    return _sscode;
}

-(NSString *)lastPage{
    if (!_lastPage || _lastPage.length <= 0) {
        _lastPage = @"-";
    }
    return _lastPage;
}

/**
 * 事件埋点
 * @author Wendy
 * @param event  事件名称
 * @param values  参数数组，按指定顺序排列
 */
+ (void)segAnalyticsEvent:(NSString *)event values:(NSArray <NSString *>*)values{
    __block NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [values enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [attributes setObject:obj forKey:[NSString stringWithFormat:@"ext%lu",(unsigned long)(idx + 1)]];
    }];
    [[SEGIAnalyticsManager sharedAnalyticsManager] segEvent:event attributes:attributes];
}
@end

